package com.example.modelandview;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.DisplayMetrics;
import android.view.View;

import java.util.ArrayList;

public class BallView extends View {
    //界面主线程的控制变量  
    private boolean drawing = false;
    //储存当前已有的球的信息  
    private ArrayList<Ball> Balls;
    //球的运动范围
    public static int WIDTH;
    public static int HEIGHT;
    private Paint mPaint;
    public static final double PI = 3.14159265;
    private Paint mPaint2;

    public BallView(Context context) {
        super(context);
        Balls = new ArrayList<Ball>();

        //加入了5个球
        Balls.add(new Ball());
        Balls.add(new Ball());
        Balls.add(new Ball());
        Balls.add(new Ball());
        Balls.add(new Ball());

        mPaint = new Paint();
        mPaint2 = new Paint();
        mPaint.setColor(Color.YELLOW);
        mPaint.setAntiAlias(true);
        mPaint2.setStyle(Paint.Style.FILL);
        mPaint2.setColor(Color.RED);
        mPaint2.setAntiAlias(true);

        DisplayMetrics dm = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);
        WIDTH = dm.widthPixels;
        HEIGHT = dm.heightPixels;
    }

    /**
     * 启动界面线程,开始自动更新界面
     */
    public void startDrawing() {
        drawing = true;
        new Thread(mRunnable).start();
    }

    private Runnable mRunnable = new Runnable() {
        //界面的主线程
        @Override
        public void run() {
            while (drawing) {
                try {
                    //更新球的位置信息
                    update();
                    //通知系统更新界面,相当于调用了onDraw函数
                    postInvalidate();
                    //界面更新的频率,这里是每30ms更新一次界面
                    Thread.sleep(30);
                    //Log.e(TAG, "drawing");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    public void stopDrawing() {
        drawing = false;
        try {
            mRunnable.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onDraw(Canvas canvas) {
        //在canvas上绘制边框  
        canvas.drawRect(0, 0, WIDTH, HEIGHT, mPaint2);
        //在canvas上绘制球  
        for (Ball Ball : Balls) {
            canvas.drawCircle(Ball.x, Ball.y, Ball.radius, mPaint);
        }
    }

    /**
     * 界面的逻辑函数,主要检查球是否发生碰撞,以及更新球的位置
     * 在每次更新前先进行碰撞检测和处理
     * 等处理完成后没有问题了，再绘制
     * 美中不足的是，该算法的碰撞处理并不保证完全可靠
     */
    private void update() {
        if (Balls.size() > 1) {
            for (int i1 = 0; i1 < Balls.size() - 1; i1++) {
                //当两个球发生碰撞,交换两个球的角度值  
                for (int i2 = i1 + 1; i2 < Balls.size(); i2++)
                    if (checkBumb(Balls.get(i1), Balls.get(i2))) {
                        Balls.get(i1).changeDerection(Balls.get(i2));
                    }
            }
        }
        //更新球的位置  
        for (Ball Ball : Balls)
            Ball.updateLocate();
    }

    /**
     * 用于检测两个小球是否发生碰撞
     * 方法是计算两个球之间的距离是否小于等于他们的半径和
     * @param c1
     * @param c2
     * @return
     */
    private boolean checkBumb(Ball c1, Ball c2) {
        return (c1.x - c2.x) * (c1.x - c2.x) + (c1.y - c2.y) * (c1.y - c2.y) <= (c1.radius + c2.radius) * (c1.radius + c2.radius);
    }
} 
